#include "include.h"

_MB_PWM_T MB_PWM;


void MeBsp_PWM_DMA_Init(void);

void MeBsp_PWM_Init(void)
{
  gpio_init_type gpio_init_struct;
  tmr_output_config_type tmr_output_struct;
  
  /* enable iomux periph clock */
  crm_periph_clock_enable(CRM_IOMUX_PERIPH_CLOCK, TRUE);
  /* enable gpioa periph clock */
  crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
  /* enable gpiob periph clock */
  crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);
  /* enable tmr2 periph clock */
  crm_periph_clock_enable(CRM_TMR2_PERIPH_CLOCK, TRUE);

  /* enable tmr3 periph clock */
  crm_periph_clock_enable(CRM_TMR3_PERIPH_CLOCK, TRUE);
  
  MeBsp_PWM_DMA_Init();
  
  /* set default parameter */
  gpio_default_para_init(&gpio_init_struct);

  gpio_init_struct.gpio_pins = GPIO_PINS_4; //PWM_OUT_Enable
  gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT;
  gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
  gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
  gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE;
  gpio_init(GPIOA, &gpio_init_struct);
  
  /* configure the CH3 pin */
  gpio_init_struct.gpio_pins = GPIO_PINS_2|GPIO_PINS_3; //PWM6,PWM5
  gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
  gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
  gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
  gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE;
  gpio_init(GPIOA, &gpio_init_struct);

  /* configure the CH1 pin */
  gpio_init_struct.gpio_pins = GPIO_PINS_6|GPIO_PINS_7; //PWM4,PWM3
  gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
  gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
  gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
  gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE;
  gpio_init(GPIOA, &gpio_init_struct);

  /* configure the CH3 pin */
  gpio_init_struct.gpio_pins = GPIO_PINS_0|GPIO_PINS_1; //PWM2,PWM1
  gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
  gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
  gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
  gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_MODERATE;
  gpio_init(GPIOB, &gpio_init_struct);

    /* configure counter settings */
  tmr_base_init(TMR2, 1023, 9);
  tmr_cnt_dir_set(TMR2, TMR_COUNT_UP);
  tmr_clock_source_div_set(TMR2, TMR_CLOCK_DIV1);
  tmr_period_buffer_enable(TMR2, FALSE);

  /* configure primary mode settings */
  tmr_sub_sync_mode_set(TMR2, FALSE);
  tmr_primary_mode_select(TMR2, TMR_PRIMARY_SEL_RESET);

  /* configure channel 3 output settings */
  tmr_output_struct.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_A;
  tmr_output_struct.oc_output_state = TRUE;
  tmr_output_struct.occ_output_state = FALSE;
  tmr_output_struct.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH;
  tmr_output_struct.occ_polarity = TMR_OUTPUT_ACTIVE_HIGH;
  tmr_output_struct.oc_idle_state = FALSE;
  tmr_output_struct.occ_idle_state = FALSE;
  tmr_output_channel_config(TMR2, TMR_SELECT_CHANNEL_3, &tmr_output_struct);
  tmr_channel_value_set(TMR2, TMR_SELECT_CHANNEL_3, 0);
  tmr_output_channel_buffer_enable(TMR2, TMR_SELECT_CHANNEL_3, TRUE);

  tmr_output_channel_immediately_set(TMR2, TMR_SELECT_CHANNEL_3, FALSE);

  /* configure channel 4 output settings */
  tmr_output_struct.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_A;
  tmr_output_struct.oc_output_state = TRUE;
  tmr_output_struct.occ_output_state = FALSE;
  tmr_output_struct.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH;
  tmr_output_struct.occ_polarity = TMR_OUTPUT_ACTIVE_HIGH;
  tmr_output_struct.oc_idle_state = FALSE;
  tmr_output_struct.occ_idle_state = FALSE;
  tmr_output_channel_config(TMR2, TMR_SELECT_CHANNEL_4, &tmr_output_struct);
  tmr_channel_value_set(TMR2, TMR_SELECT_CHANNEL_4, 0);
  tmr_output_channel_buffer_enable(TMR2, TMR_SELECT_CHANNEL_4, TRUE);

  tmr_output_channel_immediately_set(TMR2, TMR_SELECT_CHANNEL_4, FALSE);
  
  /* configure dma ch3 */
  tmr_dma_request_enable(TMR2, TMR_C3_DMA_REQUEST, TRUE);
  /* configure dma ch4 */
  tmr_dma_request_enable(TMR2, TMR_C4_DMA_REQUEST, TRUE);
  
  tmr_counter_enable(TMR2, TRUE);
  
  /* configure counter settings */
  tmr_base_init(TMR3, 1023, 9);
  tmr_cnt_dir_set(TMR3, TMR_COUNT_UP);
  tmr_clock_source_div_set(TMR3, TMR_CLOCK_DIV1);
  tmr_period_buffer_enable(TMR3, FALSE);

  /* configure primary mode settings */
  tmr_sub_sync_mode_set(TMR3, FALSE);
  tmr_primary_mode_select(TMR3, TMR_PRIMARY_SEL_RESET);

  /* configure channel 1 output settings */
  tmr_output_struct.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_A;
  tmr_output_struct.oc_output_state = TRUE;
  tmr_output_struct.occ_output_state = FALSE;
  tmr_output_struct.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH;
  tmr_output_struct.occ_polarity = TMR_OUTPUT_ACTIVE_HIGH;
  tmr_output_struct.oc_idle_state = FALSE;
  tmr_output_struct.occ_idle_state = FALSE;
  tmr_output_channel_config(TMR3, TMR_SELECT_CHANNEL_1, &tmr_output_struct);
  tmr_channel_value_set(TMR3, TMR_SELECT_CHANNEL_1, 0);
  tmr_output_channel_buffer_enable(TMR3, TMR_SELECT_CHANNEL_1, TRUE);

  tmr_output_channel_immediately_set(TMR3, TMR_SELECT_CHANNEL_1, FALSE);

  /* configure channel 2 output settings */
  tmr_output_struct.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_A;
  tmr_output_struct.oc_output_state = TRUE;
  tmr_output_struct.occ_output_state = FALSE;
  tmr_output_struct.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH;
  tmr_output_struct.occ_polarity = TMR_OUTPUT_ACTIVE_HIGH;
  tmr_output_struct.oc_idle_state = FALSE;
  tmr_output_struct.occ_idle_state = FALSE;
  tmr_output_channel_config(TMR3, TMR_SELECT_CHANNEL_2, &tmr_output_struct);
  tmr_channel_value_set(TMR3, TMR_SELECT_CHANNEL_2, 0);
  tmr_output_channel_buffer_enable(TMR3, TMR_SELECT_CHANNEL_2, TRUE);

  tmr_output_channel_immediately_set(TMR3, TMR_SELECT_CHANNEL_2, FALSE);
  
  /* configure channel 3 output settings */
  tmr_output_struct.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_A;
  tmr_output_struct.oc_output_state = TRUE;
  tmr_output_struct.occ_output_state = FALSE;
  tmr_output_struct.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH;
  tmr_output_struct.occ_polarity = TMR_OUTPUT_ACTIVE_HIGH;
  tmr_output_struct.oc_idle_state = FALSE;
  tmr_output_struct.occ_idle_state = FALSE;
  tmr_output_channel_config(TMR3, TMR_SELECT_CHANNEL_3, &tmr_output_struct);
  tmr_channel_value_set(TMR3, TMR_SELECT_CHANNEL_3, 0);
  tmr_output_channel_buffer_enable(TMR3, TMR_SELECT_CHANNEL_3, TRUE);

  tmr_output_channel_immediately_set(TMR3, TMR_SELECT_CHANNEL_3, FALSE);

  /* configure channel 4 output settings */
  tmr_output_struct.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_A;
  tmr_output_struct.oc_output_state = TRUE;
  tmr_output_struct.occ_output_state = FALSE;
  tmr_output_struct.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH;
  tmr_output_struct.occ_polarity = TMR_OUTPUT_ACTIVE_HIGH;
  tmr_output_struct.oc_idle_state = FALSE;
  tmr_output_struct.occ_idle_state = FALSE;
  tmr_output_channel_config(TMR3, TMR_SELECT_CHANNEL_4, &tmr_output_struct);
  tmr_channel_value_set(TMR3, TMR_SELECT_CHANNEL_4, 0);
  tmr_output_channel_buffer_enable(TMR3, TMR_SELECT_CHANNEL_4, TRUE);

  tmr_output_channel_immediately_set(TMR3, TMR_SELECT_CHANNEL_4, FALSE);

  /* configure dma ch1 */
  tmr_dma_request_enable(TMR3, TMR_C1_DMA_REQUEST, TRUE);
  /* configure dma ch2 */
  tmr_dma_request_enable(TMR3, TMR_C2_DMA_REQUEST, TRUE);
  /* configure dma ch3 */
  tmr_dma_request_enable(TMR3, TMR_C3_DMA_REQUEST, TRUE);
  /* configure dma ch4 */
  tmr_dma_request_enable(TMR3, TMR_C4_DMA_REQUEST, TRUE);

  tmr_counter_enable(TMR3, TRUE);
  
   /* output enable */
  tmr_output_enable(TMR3, TRUE);
  /* output enable */
  tmr_output_enable(TMR2, TRUE);
 

  
  TMR2->c3dt = 0;
  TMR2->c4dt = 0;
  
  TMR3->c1dt = 0;
  TMR3->c2dt = 0;
  TMR3->c3dt = 0;
  TMR3->c4dt = 0;
  //Out Enable
  GPIOA->scr = GPIO_PINS_4;
  
  
  dma_channel_enable(DMA1_CHANNEL1, TRUE);
  dma_channel_enable(DMA1_CHANNEL2, TRUE);
  dma_channel_enable(DMA1_CHANNEL3, TRUE);
  dma_channel_enable(DMA1_CHANNEL4, TRUE);
  dma_channel_enable(DMA1_CHANNEL5, TRUE);
  dma_channel_enable(DMA1_CHANNEL6, TRUE);
  
  
  USER_Debug_Out("--PWM Init\r\n");
}



void MeBsp_PWM_DMA_Init(void)
{
  dma_init_type dma_init_struct;
  
  /* enable dma1 periph clock */
  crm_periph_clock_enable(CRM_DMA1_PERIPH_CLOCK, TRUE);
  
  
  dma_reset(DMA1_CHANNEL1);
  dma_default_para_init(&dma_init_struct);
  dma_init_struct.direction = DMA_DIR_MEMORY_TO_PERIPHERAL;
  dma_init_struct.memory_data_width = DMA_MEMORY_DATA_WIDTH_HALFWORD;
  dma_init_struct.memory_inc_enable = TRUE;
  dma_init_struct.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_HALFWORD;
  dma_init_struct.peripheral_inc_enable = FALSE;
  dma_init_struct.priority = DMA_PRIORITY_VERY_HIGH;
  dma_init_struct.loop_mode_enable = TRUE;
  dma_init(DMA1_CHANNEL1, &dma_init_struct);

  dma_reset(DMA1_CHANNEL2);
  dma_init(DMA1_CHANNEL2, &dma_init_struct);
  
  dma_reset(DMA1_CHANNEL3);
  dma_init(DMA1_CHANNEL3, &dma_init_struct);
  
  dma_reset(DMA1_CHANNEL4);
  dma_init(DMA1_CHANNEL4, &dma_init_struct);
  
  dma_reset(DMA1_CHANNEL5);
  dma_init(DMA1_CHANNEL5, &dma_init_struct);
  
  dma_reset(DMA1_CHANNEL6);
  dma_init(DMA1_CHANNEL6, &dma_init_struct);
  
  /* flexible function enable */
  dma_flexible_config(DMA1, FLEX_CHANNEL1, DMA_FLEXIBLE_TMR2_CH3);
  dma_flexible_config(DMA1, FLEX_CHANNEL2, DMA_FLEXIBLE_TMR2_CH4);
  dma_flexible_config(DMA1, FLEX_CHANNEL3, DMA_FLEXIBLE_TMR3_CH1);
  dma_flexible_config(DMA1, FLEX_CHANNEL4, DMA_FLEXIBLE_TMR3_CH2);
  dma_flexible_config(DMA1, FLEX_CHANNEL5, DMA_FLEXIBLE_TMR3_CH3);
  dma_flexible_config(DMA1, FLEX_CHANNEL6, DMA_FLEXIBLE_TMR3_CH4);
  
  
  DMA1_CHANNEL1->dtcnt = 64;
  DMA1_CHANNEL1->paddr = (uint32_t)&TMR2->c3dt;
  DMA1_CHANNEL1->maddr = (uint32_t)&MB_PWM.wOutVal[0][0];
  
  DMA1_CHANNEL2->dtcnt = 64;
  DMA1_CHANNEL2->paddr = (uint32_t)&TMR2->c4dt;
  DMA1_CHANNEL2->maddr = (uint32_t)&MB_PWM.wOutVal[1][0];
  
  DMA1_CHANNEL3->dtcnt = 64;
  DMA1_CHANNEL3->paddr = (uint32_t)&TMR3->c1dt;
  DMA1_CHANNEL3->maddr = (uint32_t)&MB_PWM.wOutVal[2][0];
  
  DMA1_CHANNEL4->dtcnt = 64;
  DMA1_CHANNEL4->paddr = (uint32_t)&TMR3->c2dt;
  DMA1_CHANNEL4->maddr = (uint32_t)&MB_PWM.wOutVal[3][0];
  
  DMA1_CHANNEL5->dtcnt = 64;
  DMA1_CHANNEL5->paddr = (uint32_t)&TMR3->c3dt;
  DMA1_CHANNEL5->maddr = (uint32_t)&MB_PWM.wOutVal[4][0];
  
  DMA1_CHANNEL6->dtcnt = 64;
  DMA1_CHANNEL6->paddr = (uint32_t)&TMR3->c4dt;
  DMA1_CHANNEL6->maddr = (uint32_t)&MB_PWM.wOutVal[5][0];
  
  MB_PWM.wNowVal[0] = (0<<6)|0; //R
  MB_PWM.wNowVal[1] = (0<<6)|0; //G
  
  MB_PWM.wNowVal[2] = (0<<6)|0; //B
  MB_PWM.wNowVal[3] = (0<<6)|0;//W
  
  MB_PWM.wNowVal[4] = (0<<6)|0; //Y
  MB_PWM.wNowVal[5] = (0<<6)|0;//Fan
}


const uint64_t MeBsp_PWM_ValLsb_CodeTab[64]=
{
  0x0000000000000000,//0
	0x0000000080000000,//1
	0x8000000080000000,//2
	0x8000000180000000,//3
	0x8000800080008000,//4
	0x8000800180008000,//5
	0x8020080080200800,//6
	0x8020080180200800,//7
	0x8080808080808080,//8
	0x8080808180808080,//9
	0x8208208082082080,//10
	0x8208208182082080,//11
	0x8421084084210840,//12
	0x8421084184210840,//13
	0x8888888088888880,//14
	0x8888888088888888,//15
	0x8888888888888888,//16
	0x8888888988888888,//17
	0x8249241282492490,//18
	0x9249241282492490,//19
	0x9249249092492490,//20
	0x9249249092492492,//21
	0x9249249292492492,//22
	0x924924929A492492,//23
	0x924924D2924924D2,//24
	0x926924D29A492492,//25
	0x926924D29A49A492,//26
	0x9A6924D29A49A492,//27
	0x9A6924D29A49A692,//28
	0x9A69A4D29A49A692,//29
	0x9A69A4D29B49A692,//30
	0x9B69A4D29B49A692,//31
	0xAAAAAAAAAAAAAAAA,//32
	0xEAAAAAAAAAAAAAAA,//33
	0xEAAAAAAAEAAAAAAA,//34
	0xFAAAAAAAEAAAAAAA,//35
	0xFAAAAAAAFAAAAAAA,//36
	0xFEAAAAAAFAAAAAAA,//37
	0xFEAAAAAAFEAAAAAA,//38
	0xFFAAAAAAFEAAAAAA,//39
	0xFFAAAAAAFFAAAAAA,//40
	0xFFEAAAAAFFAAAAAA,//41
	0xFFEAAAAAFFEAAAAA,//42
	0xFFFAAAAAFFEAAAAA,//43
	0xFFFAAAAAFFFAAAAA,//44
	0xFFFEAAAAFFFAAAAA,//45
	0xFFFEAAAAFFFEAAAA,//46
	0xFFFFAAAAFFFEAAAA,//47
	0xFFFFAAAAFFFFAAAA,//48
	0xFFFFEAAAFFFFAAAA,//49
	0xFFFFEAAAFFFFEAAA,//50
	0xFFFFFAAAFFFFEAAA,//51
	0xFFFFFAAAFFFFFAAA,//52
	0xFFFFFEAAFFFFFAAA,//53
	0xFFFFFEAAFFFFFEAA,//54
	0xFFFFFFAAFFFFFEAA,//55
	0xFFFFFFAAFFFFFFAA,//56
	0xFFFFFFEAFFFFFFAA,//57
	0xFFFFFFEAFFFFFFEA,//58
	0xFFFFFFFAFFFFFFEA,//59
	0xFFFFFFFAFFFFFFFA,//60
	0xFFFFFFFEFFFFFFFA,//61
	0xFFFFFFFEFFFFFFFE,//62
	0xFFFFFFFFFFFFFFFF,//63
};

uint64_t MeBsp_PWM_ValLsb_CodeTab1[64];

void MeBsp_PWM_UpdataConfig(void)
{
  uint8_t update_flag;
  update_flag = 0;
  if ( MB_PWM.wDivVal != MB_DevComIn_Data.packet.wPwmDivVal ) {
    MB_PWM.wDivVal = MB_DevComIn_Data.packet.wPwmDivVal;
    update_flag = 1;
  }

  if ( MB_PWM.wPeriodVal != MB_DevComIn_Data.packet.wPwmPeriodVal ) {
    MB_PWM.wPeriodVal = MB_DevComIn_Data.packet.wPwmPeriodVal;
    update_flag = 1;
  }

  MB_PWM.bDimmerDelayEnable = MB_DevComIn_Data.packet.bPwmDelayEnable;

  if ( update_flag ) {
    TMR2->pr = MB_PWM.wPeriodVal;
    TMR2->div = MB_PWM.wDivVal;

    TMR3->pr = MB_PWM.wPeriodVal;
    TMR3->div = MB_PWM.wDivVal;
  }

}

void MeBsp_PWM_Hanl(void)
{
  uint8_t c,c1;
  uint16_t val,val_LSB;

  MeBsp_PWM_UpdataConfig();
  
  if ( !MB_DevComIn.bRecvIsConnFlag ) {
    for ( c1 = 0; c1 < 6; c1++ ) {
      for ( c = 0; c < 64; c++ ) {
        MB_PWM.wOutVal[c1][c] = 0;
      }
      MB_PWM.wOldVal[c1] = 0;
    }
    return;
  }

  for ( c1 = 0; c1 < 6; c1++ ) {
    if ( MB_PWM.wOldVal[c1] != MB_PWM.wNowVal[c1] ) {
      MB_PWM.wOldVal[c1] = MB_PWM.wNowVal[c1];
      
      val = (MB_PWM.wOldVal[c1]>>6) & 0x03FF;
      val_LSB = MB_PWM.wOldVal[c1] & 0x003F;
      for ( c = 0; c < 64; c++ ) {
        MB_PWM.wOutVal[c1][c] = val;
        MB_PWM.wOutVal[c1][c] += (MeBsp_PWM_ValLsb_CodeTab[val_LSB]>>c)&0x01;
      }
    }
  }
  
}
